package cn.ibdsr.human.util;

import cn.ibdsr.human.constant.BizConstants;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.util.Date;

/**
 * JWT的工具类
 * @author chenglx
 * @version V1.0
 * @date 2020/11/12 17:17
 * <p>
 * Date Author Description
 * ------------------------------------------------------
 * 2020/11/12 chenglx init
 */
@Slf4j
public class JwtUtils {

    /**
     * ^&*($^&230OIU)fjalL:kad
     */
    private static final String SECRET_KEY = "XiYqKCReJjIzME9JVSlmamFsTDprYWQ=";
    /**
     * 有效期（毫秒）：90天
     */
    private static final long VALID_DURATION = 90L * 24 * 3600 * 1000;

    /**
     * 解析JWT的token，返回解析后的Claims
     * @param token
     * @return
     */
    public static Claims resolveToken(String token) {
        // todo 是否可用单例模式
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(SECRET_KEY)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            if (e instanceof ExpiredJwtException) {
                // 在 parseClaimsJws() 可能会抛出 ExpiredJwtException
                log.warn("resolveToken(): 解析token出错：token: {}", token, e);
            } else {
                log.error("resolveToken(): 解析token出错：token: {}", token, e);
            }
            return null;
        }

        if (claims == null) {
            log.warn("resolveToken(): token解析结果为空：token: {}", token);
            return null;
        }
        Date expirationDate = claims.getExpiration();
        if (expirationDate.getTime() <= System.currentTimeMillis()) {
            log.warn("resolveToken(): JWT token已过期：token: {}; issueDate: {}, expirationDate: {}", token,
                    DateFormatUtils.format(claims.getIssuedAt(), BizConstants.DATETIME_PATTERN),
                    DateFormatUtils.format(expirationDate, BizConstants.DATETIME_PATTERN));
            // 过期则返回空
            return null;
        }
        log.debug("resolveToken(): claims: {}", JSON.toJSONString(claims));
        // return Long.valueOf(claims.getSubject())
        return claims;
    }

    /**
     * 生成JWT的token
     * @param id
     * @return
     */
    public static String buildToken(Long id) {
        Date now = new Date();
        Date expiration = new Date(now.getTime() + VALID_DURATION);
        // todo 是否可用单例模式
        JwtBuilder builder = Jwts.builder()
                .setSubject(id.toString())
                .setIssuer("zoufang")
                .setIssuedAt(now)
                .setNotBefore(now)
                .setExpiration(expiration)
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY);
        return builder.compact();
    }

    /**
     * 获取JWT的payload部分
     * @param token
     * @return
     */
    private static Claims getClaimFromToken(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
    }

    /**
     *  验证token是否失效
     *  true:过期   false:没过期
     * </pre>
     */
//    public static Boolean isTokenExpired(String token) {
//        try {
//            final Date expiration = getExpirationDateFromToken(token);
//            return expiration.before(new Date());
//        } catch (ExpiredJwtException | MalformedJwtException exception) {
//            return true;
//        }
//    }


    public static void main(String[] args) {
        String token = JwtUtils.buildToken(25L);
        System.out.println(token);
        System.out.println(JwtUtils.resolveToken(token).getSubject());

        long a = 5L * 24 * 3600 * 1000;
        System.out.println(5 * 24 * 3600 * 1000);
        System.out.println((a == 7776000000L) + " " + a + " " + Long.MAX_VALUE + " " + Integer.MAX_VALUE);
    }
}
